﻿using Senparc.Weixin;
using Senparc.Weixin.MP;
using Senparc.Weixin.MP.AdvancedAPIs;
using Senparc.Weixin.MP.AdvancedAPIs.OAuth;
using Senparc.Weixin.MP.TenPayLibV3;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Xml.Linq;
using WeixinPayService.Models;

namespace WeixinPayService.Service
{
    public static class WeixinPay
    {
        private static TenPayV3Info _tenPayV3Info;
        public static TenPayV3Info TenPayV3Info
        {
            get
            {
                if (_tenPayV3Info == null)
                {
                    _tenPayV3Info = TenPayInfoRegister.Register();
                }
                return _tenPayV3Info;
            }
        }
        /// <summary>
        /// 授权页后跳转
        /// </summary>
        /// <param name="accId">自定义信息(提交给微信 微信支付完成后 微信原样返回)</param>
        /// <param name="orderNumber">订单号</param>
        /// <param name="returnUrl">微信支付页</param>
        /// <param name="authType">
        ///		授权类型 
        ///			0-用户无感知授权 商家只获取用户openId 
        ///			1-用户需要点击按钮后授权 商家获取更多用户信息
        /// </param>
        /// <returns></returns>
        public static string OAuthReturnUrl(string attachInfo, string orderNumber, string returnUrl)
        {
            //这里的state只负责传递参数
            string state = string.Format("{0}|{1}", orderNumber, attachInfo);
            //默默处理授权 只获取用户 openId
            return OAuthApi.GetAuthorizeUrl(TenPayV3Info.AppId, returnUrl, state, OAuthScope.snsapi_base);
        }

        /// <summary>
        /// 统一支付获取预付Id 并获取微信H5支付参数
        /// </summary>
        /// <param name="code"></param>
        /// <param name="state"></param>
        /// <param name="productName">商品名称</param>
        /// <param name="totalFee">总价格</param>
        /// <param name="userHostAddress">用户公网IP</param>
        /// <returns>微信H5支付参数</returns>
        public static BrandWCPay GetBrandWCPay(string code, string state, string userHostAddress)
        {
            BrandWCPay model = new BrandWCPay();
            if (string.IsNullOrEmpty(code))
            {
                model.errorCode = "0001";
                model.errorDesc = "用户拒绝了授权";
                return model;
            }
            if (!state.Contains("|"))
            {
                model.errorCode = "0002";
                model.errorDesc = "非法访问";
                return model;
            }
            //总价 订单编号|总费用|用户ID+订单编号|state = "OrderNumber|totalFee|userId+OrderNumber"
            string[] stateData = state.Split('|');
            string productName = "";
            int totalFee = 0;
            string orderNumber = "";
            if (stateData.Length == 3)
            {
                orderNumber = stateData[0];
                totalFee = Convert.ToInt32(Convert.ToDecimal(stateData[1]) * 100);  //微信支付金额单位为分 这里需要做一次转化
                productName = string.Format("便利超人-订单编号{0}", orderNumber);
            }
            else
            {
                model.errorCode = "0003";
                model.errorDesc = "没有有效的商品";
                return model;
            }
            //用code换取access_token
            OAuthAccessTokenResult openIdResult = OAuthApi.GetAccessToken(TenPayV3Info.AppId, TenPayV3Info.AppSecret, code);
            if (openIdResult.errcode != ReturnCode.请求成功)
            {
                model.errorCode = "0004";
                model.errorDesc = "错误：" + openIdResult.errmsg;
                return model;
            }

            //创建支付应答对象
            RequestHandler packageReqHandler = new RequestHandler(null);
            //初始化
            packageReqHandler.Init();

            model.appId = TenPayV3Info.AppId;
            model.timeStamp = TenPayV3Util.GetTimestamp();
            model.nonceStr = TenPayV3Util.GetNoncestr();
            //设置package订单参数
            packageReqHandler.SetParameter("appid", TenPayV3Info.AppId);		  //公众账号ID
            packageReqHandler.SetParameter("mch_id", TenPayV3Info.MchId);		  //商户号
            packageReqHandler.SetParameter("nonce_str", model.nonceStr);		//随机字符串
            packageReqHandler.SetParameter("body", productName);    //商品信息
            packageReqHandler.SetParameter("device_info", "WEB");		//终端设备号(门店号或收银设备ID)，注意：PC网页或公众号内支付请传"WEB"
            packageReqHandler.SetParameter("attach", state);		//商家自定义信息
            packageReqHandler.SetParameter("out_trade_no", orderNumber);		//商家订单号
            packageReqHandler.SetParameter("total_fee", totalFee.ToString());		//商品金额，以分为单位(money * 100).ToString()
            packageReqHandler.SetParameter("spbill_create_ip", userHostAddress);   //用户的公网ip，不是商户服务器IP
            packageReqHandler.SetParameter("notify_url", TenPayV3Info.TenPayV3Notify);		    //接收财付通通知的URL
            packageReqHandler.SetParameter("trade_type", TenPayV3Type.JSAPI.ToString());		//交易类型
            packageReqHandler.SetParameter("openid", openIdResult.openid);		//用户的openId

            string sign = packageReqHandler.CreateMd5Sign("key", TenPayV3Info.Key);
            packageReqHandler.SetParameter("sign", sign);		//签名

            string data = packageReqHandler.ParseXML();
            //调用统一支付接口 返回预支付订单号
            string result = TenPayV3.Unifiedorder(data);
            var res = XDocument.Parse(result);
            string prepayId = res.Element("xml").Element("prepay_id").Value;
            model.package = string.Format("prepay_id={0}", prepayId);
            model.signType = "MD5";
            //设置支付参数
            RequestHandler paySignReqHandler = new RequestHandler(null);
            paySignReqHandler.SetParameter("appId", model.appId);
            paySignReqHandler.SetParameter("timeStamp", model.timeStamp);
            paySignReqHandler.SetParameter("nonceStr", model.nonceStr);
            paySignReqHandler.SetParameter("package", model.package);
            paySignReqHandler.SetParameter("signType", model.signType);
            model.paySign = paySignReqHandler.CreateMd5Sign("key", TenPayV3Info.Key);
            model.errorCode = "0000";
            model.errorDesc = "预下单成功";
            return model;
        }

        /// <summary>
        /// 订单回调处理
        /// </summary>
        /// <param name="resHandler">相应处理实体</param>
        /// <returns>1-交易成功 2-交易失败 3-通信失败 4-非法订单</returns>
        public static int PayNotifyCode(ResponseHandler resHandler)
        {
            int orderStatus = 0;
            //return_code字段是通信标识，非交易标识，交易是否成功需要查看result_code来判断
            string return_code = resHandler.GetParameter("return_code");
            string result_code = resHandler.GetParameter("result_code");
            resHandler.SetKey(TenPayV3Info.Key);
            //验证请求是否从微信发过来（安全）
            if (resHandler.IsTenpaySign())
            {
                if (return_code == "SUCCESS")	//通信成功
                {
                    if (result_code == "SUCCESS")	//交易成功
                    {
                        orderStatus = 1;
                    }
                    else	//交易失败
                    {
                        orderStatus = 2;
                    }
                }
                else	//通信失败
                {
                    orderStatus = 3;
                }
            }
            else	//非法订单
            {
                orderStatus = 4;
            }
            return orderStatus;
        }
    }

}